
#ifndef  RECOVERY_ERRNOSTATUS_H
#define  RECOVERY_ERRNOSTATUS_H

#include "recovery/Status.h"

namespace recovery {

class ErrnoStatus : public Status {
    using Code = Status::Code;
public:
	operator bool() const{
		return isOK();
	}
    bool isOK() const override {
        return Status::isOK() && _errno == 0;
    }

    static ErrnoStatus OK(){
        return ErrnoStatus(Code::kOK, 0, "");
    }

    std::string what() const override;
    Status toStatus(const std::string_view & msg = "") const override;

	ErrnoStatus(const ErrnoStatus & right);
	ErrnoStatus & operator =(const ErrnoStatus & right);

	ErrnoStatus(const ErrnoStatus && right);
	ErrnoStatus & operator =(const ErrnoStatus && right);

	bool operator == (const ErrnoStatus & right) const {
		return Status::operator==(right) && _errno == right._errno;
	}
	bool operator != (const ErrnoStatus & right) const{
		return Status::operator!=(right) || _errno != right._errno;
	}

    static ErrnoStatus Error(int _errno = 0, const std::string_view & msg = ""){
        return ErrnoStatus(Code::kErrno, _errno, msg);
    }

protected:
    ErrnoStatus(Code code=Code::kErrno, int _errno = 0, const std::string_view & msg = "");
private:
    virtual const char *  getErrnoState(int _errno) const ;
    int _errno;
};

inline ErrnoStatus::ErrnoStatus(Code code, int _errno, const std::string_view & msg)
:Status(code, msg)
, _errno(_errno)
{
}
inline ErrnoStatus::ErrnoStatus(const ErrnoStatus & right)
: Status(right)
, _errno(right._errno)
{
}
inline ErrnoStatus & ErrnoStatus::operator =(const ErrnoStatus & right){
	if(this != &right){
		Status::operator=(right);
		_errno = right._errno;
	}
	return *this;
}
inline ErrnoStatus::ErrnoStatus(const ErrnoStatus && right)
: Status(std::move(right))
, _errno(std::move(right._errno))
{
}
inline ErrnoStatus & ErrnoStatus::operator =(const ErrnoStatus && right){
	if(this != &right){
		Status::operator=(std::move(right));
		_errno = std::move(right._errno);
	}
	return *this;
}

}// end of namespace recovery

#endif   /* RECOVERY_ERRNOSTATUS_H */
